home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 2010 April / PCWorld0410.iso / hity wydania / Ubuntu 9.10 PL / karmelkowy-koliberek-desktop-9.10-i386-PL.iso / casper / filesystem.squashfs / usr / share / hplip / base / g.py < prev    next >
Text File  |  2009-10-09  |  12KB  |  345 lines

  1. # -*- coding: utf-8 -*-
  2. #
  3. # (c) Copyright 2003-2009 Hewlett-Packard Development Company, L.P.
  4. #
  5. # This program is free software; you can redistribute it and/or modify
  6. # it under the terms of the GNU General Public License as published by
  7. # the Free Software Foundation; either version 2 of the License, or
  8. # (at your option) any later version.
  9. #
  10. # This program is distributed in the hope that it will be useful,
  11. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13. # GNU General Public License for more details.
  14. #
  15. # You should have received a copy of the GNU General Public License
  16. # along with this program; if not, write to the Free Software
  17. # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  18. #
  19. # Author: Don Welch
  20. #
  21. # NOTE: This module is safe for 'from g import *'
  22. #
  23.  
  24. # Std Lib
  25. import sys
  26. import os
  27. import os.path
  28. import ConfigParser
  29. import locale
  30. import pwd
  31. import stat
  32. import re
  33.  
  34. # Local
  35. from codes import *
  36. import logger
  37.  
  38. # System wide logger
  39. log = logger.Logger('', logger.Logger.LOG_LEVEL_INFO, logger.Logger.LOG_TO_CONSOLE)
  40. log.set_level('info')
  41.  
  42.  
  43. MINIMUM_PYQT_MAJOR_VER = 3
  44. MINIMUM_PYQT_MINOR_VER = 14
  45. MINIMUM_QT_MAJOR_VER = 3
  46. MINIMUM_QT_MINOR_VER = 0
  47.  
  48.  
  49. def to_bool(s, default=False):
  50.     if isinstance(s, str) and s:
  51.         if s[0].lower() in ['1', 't', 'y']:
  52.             return True
  53.         elif s[0].lower() in ['0', 'f', 'n']:
  54.             return False
  55.     elif isinstance(s, bool):
  56.         return s
  57.  
  58.     return default
  59.  
  60.  
  61. # System wide properties
  62. class Properties(dict):
  63.  
  64.     def __getattr__(self, attr):
  65.         if attr in self.keys():
  66.             return self.__getitem__(attr)
  67.         else:
  68.             return ""
  69.  
  70.     def __setattr__(self, attr, val):
  71.         self.__setitem__(attr, val)
  72.  
  73. prop = Properties()
  74.  
  75.  
  76.  
  77. class ConfigBase(object):
  78.     def __init__(self, filename):
  79.         self.filename = filename
  80.         self.conf = ConfigParser.ConfigParser()
  81.         self.read()
  82.  
  83.  
  84.     def get(self, section, key, default=u''):
  85.         try:
  86.             return self.conf.get(section, key)
  87.         except (ConfigParser.NoOptionError, ConfigParser.NoSectionError):
  88.             return default
  89.  
  90.  
  91.     def set(self, section, key, value):
  92.         if not self.conf.has_section(section):
  93.             self.conf.add_section(section)
  94.  
  95.         self.conf.set(section, key, value)
  96.         self.write()
  97.  
  98.  
  99.     def sections(self):
  100.         return self.conf.sections()
  101.  
  102.  
  103.     def has_section(self, section):
  104.         return self.conf.has_section(section)
  105.  
  106.  
  107.     def options(self, section):
  108.         return self.conf.options(section)
  109.  
  110.     keys = options
  111.  
  112.     def read(self):
  113.         if self.filename is not None:
  114.             filename = self.filename
  115.             if filename.startswith("/root/"):
  116.                 # Don't try opening a file in root's home directory.
  117.                 log.error("attempted to read from '%s'" % self.filename)
  118.                 return
  119.             try:
  120.                 fp = open(self.filename, "r")
  121.                 self.conf.readfp(fp)
  122.                 fp.close()
  123.             except (OSError, IOError):
  124.                 log.debug("Unable to open file %s for reading." % self.filename)
  125.  
  126.     def write(self):
  127.         if self.filename is not None:
  128.             filename = self.filename
  129.             if filename.startswith("/root/") or filename.startswith("/etc/"):
  130.                 # Don't try writing a file in root's home directory or
  131.                 # the system-wide config file.
  132.                 # See bug #479178.
  133.                 log.error("attempted to write to '%s'" % self.filename)
  134.                 return
  135.  
  136.             try:
  137.                 fp = open(self.filename, "w")
  138.                 self.conf.write(fp)
  139.                 fp.close()
  140.             except (OSError, IOError):
  141.                 log.debug("Unable to open file %s for writing." % self.filename)
  142.  
  143.  
  144.  
  145. class SysConfig(ConfigBase):
  146.     def __init__(self):
  147.         ConfigBase.__init__(self, '/etc/hp/hplip.conf')
  148.  
  149.  
  150. class State(ConfigBase):
  151.     def __init__(self):
  152.         ConfigBase.__init__(self, '/var/lib/hp/hplip.state')
  153.  
  154.  
  155. class UserConfig(ConfigBase):
  156.     def __init__(self):
  157.         if not os.geteuid() == 0:
  158.             prop.user_dir = os.path.expanduser('~/.hplip')
  159.  
  160.             try:
  161.                 if not os.path.exists(prop.user_dir):
  162.                     os.makedirs(prop.user_dir)
  163.             except OSError:
  164.                 pass # This is sometimes OK, if running hpfax: for example
  165.  
  166.             prop.user_config_file = os.path.join(prop.user_dir, 'hplip.conf')
  167.  
  168.             if not os.path.exists(prop.user_config_file):
  169.                 try:
  170.                     file(prop.user_config_file, 'w').close()
  171.                     s = os.stat(os.path.dirname(prop.user_config_file))
  172.                     os.chown(prop.user_config_file, s[stat.ST_UID], s[stat.ST_GID])
  173.                 except IOError:
  174.                     pass
  175.  
  176.             ConfigBase.__init__(self, prop.user_config_file)
  177.  
  178.         else:
  179.             # If running as root, conf file is None
  180.             prop.user_dir = None
  181.             prop.user_config_file = None
  182.             ConfigBase.__init__(self, None)
  183.  
  184.  
  185.     def workingDirectory(self):
  186.         t = self.get('last_used', 'working_dir', os.path.expanduser("~"))
  187.         try:
  188.             t = t.decode('utf-8')
  189.         except UnicodeError:
  190.             log.error("Invalid unicode: %s"  % t)
  191.         log.debug("working directory: %s" % t)
  192.         return t
  193.  
  194.  
  195.     def setWorkingDirectory(self, t):
  196.         self.set('last_used', 'working_dir', t.encode('utf-8'))
  197.         log.debug("working directory: %s" % t.encode('utf-8'))
  198.  
  199.  
  200.  
  201. os.umask(0037)
  202.  
  203. # System Config File: Directories and build settings. Not altered after installation.
  204. sys_conf = SysConfig()
  205.  
  206. # System State File: System-wide runtime settings
  207. sys_state = State()
  208.  
  209. # Per-user Settings File: (Note: For Qt4 code, limit the use of this to non-GUI apps. only)
  210. user_conf = UserConfig()
  211.  
  212.  
  213. # Language settings
  214. try:
  215.     prop.locale, prop.encoding = locale.getdefaultlocale()
  216. except ValueError:
  217.     prop.locale = 'en_US'
  218.     prop.encoding = 'UTF8'
  219.  
  220. prop.version = sys_conf.get('hplip', 'version', '0.0.0') # e.g., 3.9.2b.10
  221. _p, _x = re.compile(r'(\d\w*)', re.I), []
  222. for _y in prop.version.split('.')[:3]:
  223.     _z = _p.match(_y)
  224.     if _z is not None:
  225.         _x.append(_z.group(1))
  226.  
  227. prop.installed_version = '.'.join(_x) # e.g., '3.9.2'
  228. try:
  229.     prop.installed_version_int = int(''.join(['%02x' % int(_y) for _y in _x]), 16) # e.g., 0x030902 -> 198914
  230. except ValueError:
  231.     prop.installed_version_int = 0
  232.  
  233. prop.home_dir = sys_conf.get('dirs', 'home', os.path.realpath(os.path.normpath(os.getcwd())))
  234. prop.username = pwd.getpwuid(os.getuid())[0]
  235. pdb = pwd.getpwnam(prop.username)
  236. prop.userhome = pdb[5]
  237.  
  238. prop.history_size = 50
  239.  
  240. prop.data_dir = os.path.join(prop.home_dir, 'data')
  241. prop.image_dir = os.path.join(prop.home_dir, 'data', 'images')
  242. prop.xml_dir = os.path.join(prop.home_dir, 'data', 'xml')
  243. prop.models_dir = os.path.join(prop.home_dir, 'data', 'models')
  244. prop.localization_dir = os.path.join(prop.home_dir, 'data', 'localization')
  245.  
  246. prop.max_message_len = 8192
  247. prop.max_message_read = 65536
  248. prop.read_timeout = 90
  249.  
  250. prop.ppd_search_path = '/usr/share;/usr/local/share;/usr/lib;/usr/local/lib;/usr/libexec;/opt;/usr/lib64'
  251. prop.ppd_search_pattern = 'HP-*.ppd.*'
  252. prop.ppd_download_url = 'http://www.linuxprinting.org/ppd-o-matic.cgi'
  253. prop.ppd_file_suffix = '-hpijs.ppd'
  254.  
  255. # Build and install configurations
  256. prop.gui_build = to_bool(sys_conf.get('configure', 'gui-build', '0'))
  257. prop.net_build = to_bool(sys_conf.get('configure', 'network-build', '0'))
  258. prop.par_build = to_bool(sys_conf.get('configure', 'pp-build', '0'))
  259. prop.usb_build = True
  260. prop.scan_build = to_bool(sys_conf.get('configure', 'scanner-build', '0'))
  261. prop.fax_build = to_bool(sys_conf.get('configure', 'fax-build', '0'))
  262. prop.doc_build = to_bool(sys_conf.get('configure', 'doc-build', '0'))
  263. prop.foomatic_xml_install = to_bool(sys_conf.get('configure', 'foomatic-xml-install', '0'))
  264. prop.foomatic_ppd_install = to_bool(sys_conf.get('configure', 'foomatic-ppd-install', '0'))
  265. prop.hpcups_build = to_bool(sys_conf.get('configure', 'hpcups-install', '0'))
  266. prop.hpijs_build = to_bool(sys_conf.get('configure', 'hpijs-install', '0'))
  267.  
  268. # Spinner, ala Gentoo Portage
  269. spinner = "\|/-\|/-"
  270. spinpos = 0
  271.  
  272. def update_spinner():
  273.     global spinner, spinpos
  274.     if not log.is_debug() and sys.stdout.isatty():
  275.         sys.stdout.write("\b" + spinner[spinpos])
  276.         spinpos=(spinpos + 1) % 8
  277.         sys.stdout.flush()
  278.  
  279. def cleanup_spinner():
  280.     if not log.is_debug() and sys.stdout.isatty():
  281.         sys.stdout.write("\b \b")
  282.         sys.stdout.flush()
  283.  
  284.  
  285. # Internal/messaging errors
  286.  
  287. ERROR_STRINGS = {
  288.                 ERROR_SUCCESS : 'No error',
  289.                 ERROR_UNKNOWN_ERROR : 'Unknown error',
  290.                 ERROR_DEVICE_NOT_FOUND : 'Device not found',
  291.                 ERROR_INVALID_DEVICE_ID : 'Unknown/invalid device-id field',
  292.                 ERROR_INVALID_DEVICE_URI : 'Unknown/invalid device-uri field',
  293.                 ERROR_DATA_LENGTH_EXCEEDS_MAX : 'Data length exceeds maximum',
  294.                 ERROR_DEVICE_IO_ERROR : 'Device I/O error',
  295.                 ERROR_NO_PROBED_DEVICES_FOUND : 'No probed devices found',
  296.                 ERROR_DEVICE_BUSY : 'Device busy',
  297.                 ERROR_DEVICE_STATUS_NOT_AVAILABLE : 'DeviceStatus not available',
  298.                 ERROR_INVALID_SERVICE_NAME : 'Invalid service name',
  299.                 ERROR_ERROR_INVALID_CHANNEL_ID : 'Invalid channel-id (service name)',
  300.                 ERROR_CHANNEL_BUSY : 'Channel busy',
  301.                 ERROR_DEVICE_DOES_NOT_SUPPORT_OPERATION : 'Device does not support operation',
  302.                 ERROR_DEVICEOPEN_FAILED : 'Device open failed',
  303.                 ERROR_INVALID_DEVNODE : 'Invalid device node',
  304.                 ERROR_INVALID_HOSTNAME : "Invalid hostname ip address",
  305.                 ERROR_INVALID_PORT_NUMBER : "Invalid JetDirect port number",
  306.                 ERROR_NO_CUPS_QUEUE_FOUND_FOR_DEVICE : "No CUPS queue found for device.",
  307.                 ERROR_DATFILE_ERROR: "DAT file error",
  308.                 ERROR_INVALID_TIMEOUT: "Invalid timeout",
  309.                 ERROR_IO_TIMEOUT: "I/O timeout",
  310.                 ERROR_FAX_INCOMPATIBLE_OPTIONS: "Incompatible fax options",
  311.                 ERROR_FAX_INVALID_FAX_FILE: "Invalid fax file",
  312.                 ERROR_FAX_FILE_NOT_FOUND: "Fax file not found",
  313.                 ERROR_INTERNAL : 'Unknown internal error',
  314.                }
  315.  
  316.  
  317. class Error(Exception):
  318.     def __init__(self, opt=ERROR_INTERNAL):
  319.         self.opt = opt
  320.         self.msg = ERROR_STRINGS.get(opt, ERROR_STRINGS[ERROR_INTERNAL])
  321.         log.debug("Exception: %d (%s)" % (opt, self.msg))
  322.         Exception.__init__(self, self.msg, opt)
  323.  
  324.  
  325. # Make sure True and False are avail. in pre-2.2 versions
  326. try:
  327.     True
  328. except NameError:
  329.     True = (1==1)
  330.     False = not True
  331.  
  332. # as new translations are completed, add them here
  333. supported_locales =  { 'en_US': ('us', 'en', 'en_us', 'american', 'america', 'usa', 'english'),}
  334. # Localization support was disabled in 3.9.2
  335.                        #'zh_CN': ('zh', 'cn', 'zh_cn' , 'china', 'chinese', 'prc'),
  336.                        #'de_DE': ('de', 'de_de', 'german', 'deutsche'),
  337.                        #'fr_FR': ('fr', 'fr_fr', 'france', 'french', 'fran├ºais'),
  338.                        #'it_IT': ('it', 'it_it', 'italy', 'italian', 'italiano'),
  339.                        #'ru_RU': ('ru', 'ru_ru', 'russian'),
  340.                        #'pt_BR': ('pt', 'br', 'pt_br', 'brazil', 'brazilian', 'portuguese', 'brasil', 'portuguesa'),
  341.                        #'es_MX': ('es', 'mx', 'es_mx', 'mexico', 'spain', 'spanish', 'espanol', 'espa├▒ol'),
  342.                      #}
  343.  
  344.  
  345.